/*
 * Login
 * 
 * Version information
 * 
 * Apr 16, 2006
 * 
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.management.webapp.struts.action;

import static net.amsoft.iservice.util.IServiceConstants.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.amsoft.iservice.management.service.IBrokerManagerService;
import net.amsoft.iservice.management.util.IBrokerConstants;
import net.amsoft.iservice.management.webapp.dataObject.LoginData;
import net.amsoft.iservice.management.webapp.struts.form.LoginForm;
import net.amsoft.iservice.isso.client.ISSOClient;
import net.amsoft.iservice.util.IServiceUtil;
import net.amsoft.iservice.util.MetaData;
import net.amsoft.iservice.util.ResolverClient;
import net.amsoft.iservice.util.exception.IServiceException;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**
 * @author mohit
 *  
 */
public class Login extends BaseAction {

    public ActionForward process(ActionMapping oMapping, ActionForm oForm,
            HttpServletRequest oRequest, HttpServletResponse oResponse)
            throws Exception {
        LoginData oLoginData = (LoginData) oRequest.getSession(false)
                .getAttribute(IBrokerConstants.SESSION_LOGIN_OBJ);
        LoginForm oLoginForm = (LoginForm) oForm;
        String sServerName = oRequest.getServerName();
        IServiceUtil.log(INFO, this, F_PROCESS + "entry");

        if (oLoginForm == null || oLoginForm.getSynonym() == null) {
            IServiceUtil.log(WARN, this, F_PROCESS + "invalid synonym");
            IServiceUtil.log(DEBUG, this, F_PROCESS + "redirect to=" + IBrokerConstants.FWD_CHKLOGIN);
            return oMapping.findForward(IBrokerConstants.FWD_CHKLOGIN);
        }
        
        ActionMessages oMsgs = new ActionErrors();
        MetaData oMetaData = ResolverClient.getFinalMetaData(oLoginForm
                .getSynonym());
        if (oMetaData == null)
        {
            IServiceUtil.log(ERROR, this, F_PROCESS + " metadata=null");
            oMsgs.add(ActionMessages.GLOBAL_MESSAGE, 
                    		new ActionMessage(IBrokerConstants.ERR_INVALID_INAME));
            saveErrors(oRequest.getSession(), oMsgs);
            IServiceUtil.log(DEBUG, this, F_PROCESS + "redirect to=" + 
            		oMapping.getInputForward());
            return oMapping.getInputForward();
        }

        // Verify Admin based on service selected
        boolean isAdmin = false;
        try
        {
            isAdmin = IBrokerManagerService.verifyAdmin(
                    oLoginForm.getIBroker(), oLoginForm.getSynonym(), oLoginForm.getService());
        }
        catch (IServiceException oE)
        {
            IServiceUtil.log(ERROR, this, F_PROCESS + " exception=" + oE.getMessage());
            oMsgs.add(ActionMessages.GLOBAL_MESSAGE,
                    		new ActionMessage(IBrokerConstants.ERR_INVALID_ADMIN));
            saveErrors(oRequest, oMsgs);
            IServiceUtil.log(DEBUG, this, F_PROCESS + "redirect to=" + 
            		oMapping.getInputForward());
            return oMapping.getInputForward();
        }
        
        if (!isAdmin)
        {
            IServiceUtil.log(WARN, this, F_PROCESS + " invalid admin");
            oMsgs.add(ActionMessages.GLOBAL_MESSAGE,
                    		new ActionMessage(IBrokerConstants.ERR_INVALID_ADMIN));
            saveErrors(oRequest, oMsgs);
            IServiceUtil.log(DEBUG, this, F_PROCESS + "redirect to=" + 
            		oMapping.getInputForward());
            return oMapping.getInputForward();
        }

        //Verify iname based on service selected
        if (!IBrokerManagerService.verifySynonym(oMetaData.getGlobalInumber(),
                oLoginForm.getSynonym(), oLoginForm.getIBroker(), oLoginForm.getService())) {
            IServiceUtil.log(WARN, this, F_PROCESS + " SYN=" + oLoginForm.getSynonym());
            oMsgs.add(ActionMessages.GLOBAL_MESSAGE,
                    	new ActionMessage(IBrokerConstants.ERR_INVALID));
            saveErrors(oRequest, oMsgs);
            IServiceUtil.log(DEBUG, this, F_PROCESS + "redirect to=" + 
            		oMapping.getInputForward());
            return oMapping.getInputForward();
        }

        String sISSOUrl = oMetaData.getISSOUrl();
        String providerID = oMetaData.getProviderID();
        String sSPXri = IBrokerConstants.getSPXri(sServerName);
        
        String[] authnContext = IBrokerConstants.RAC_NAMES_LIST.split(",");
        String sComparison = IBrokerConstants.RAC_COMPARISON_TYPE;
        String sAuthRequest = ISSOClient.createSAMLAuthRequest(
                oMetaData.getGlobalInumber(), "", sSPXri, 
                false, sServerName, false, authnContext, sComparison);

        String sRelayState = IServiceUtil.generateUniqueID();
        oLoginData.setLoggedInSynonym(oLoginForm.getSynonym());
        oLoginData.setGlobalInumber(oMetaData.getGlobalInumber());
        oLoginData.setRelayState(sRelayState);
        oLoginData.setProviderID(providerID);
        oLoginData.setProviderIDHash(IServiceUtil.getOneWayEncValue(providerID));
        oLoginData.setService(oLoginForm.getService());
        oLoginData.setIBroker(oLoginForm.getIBroker());
        oLoginData.setIDPMetaDataEP(oMetaData.getServiceEndPoint());

        IServiceUtil.log(DEBUG, this, F_PROCESS + "redirect to=" + sISSOUrl);
        return new ActionForward(ISSOClient.getRedirectRequestURI(sISSOUrl,
                						sAuthRequest, sRelayState), true);
    }
}